Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Single instance on a Smartphone (not true with .NET)

208 views
Skip to first unread message

Sylvain Fortin

unread,
Apr 1, 2005, 5:05:03 PM4/1/05
to
Hi everyone,

I'm currently designing a VB.NET application for a Smartphone. The
Smartphone itself will prevent you from starting multiple instances of the
same application. Which is true only if your application is fully loaded in
memory. By clicking on the application icon repeatedly multiple instances of
the application will be started and they will run until you close them.

I tried to use Named Mutex and FindWindow but nothing works. I can still
start multiple instances of the same VB.NET application. How can I prevent
multiple instances in a VB.NET application running on a Smarthpone?

One more question, is it normal that an empty application takes up to 3
seconds to start?

Chris Tacke, eMVP

unread,
Apr 1, 2005, 5:15:49 PM4/1/05
to
The reason it loads is likely because you'e started teh second instance
before the runtime has checked in the first. You said a named mutex isn't
working? I don't see how that's possible since one instance is going to get
to create it first, and subsequent instances will only get the existing one.
Can you show your mutex code?

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message
news:595B3013-673B-432A...@microsoft.com...

Sylvain Fortin

unread,
Apr 1, 2005, 5:35:05 PM4/1/05
to
Hi Chris,

I know it doesn't make any sense and to answer your question I'm using the
example everyone is talking about on this forum:

http://www.gotdotnet.com/userfiles/jonwells/OneInstance.zip

And the following code has been added to my application:

Private oOneInstance AS OneInstance = Nothing
...

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
oOneInstance = New OneInstance(Me)
End Sub

Thanks for your time Chris.

Sylvain Fortin

Alex Feinman [MVP]

unread,
Apr 1, 2005, 7:15:01 PM4/1/05
to
The way .NET runtime maintains a single instance relies on the hidden window
of a class #NETCF_AGL_PARK with the title set to the application .exe path.
Until this window is instantiated, the next instance will launch as if the
app was not yet running. This should explain what you are seeing.

The larger your application becomes, the longer it takes to load it (simply
load into memory and JIT - I'm not talking about your .NET code), making
this window also larger. The only way around it I can think of is to use a
small and efficient launcher, which would check for your app to be already
running by enumerating the precesses

--
Alex Feinman
---
Visit http://www.opennetcf.org


"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message
news:595B3013-673B-432A...@microsoft.com...

Sylvain Fortin

unread,
Apr 1, 2005, 7:51:04 PM4/1/05
to
Hi Alex,

That's exactly what I thought, but if you read my first post, you'll see
that I'm asking if it's normal for an empty application (single form, no
menu, etc.) to take up to 3 seconds to load.

With that kind of load time on a .NET application startup, there's no way to
do anything about my multiple instance problem. But there's maybe a work
around. Can I build that small and efficient launcher application using
embedded Microsoft Visual C++ 4 and count the number of processes running in
this application?

Thanks for your time Alex.

Sylvain Fortin

Alex Feinman [MVP]

unread,
Apr 1, 2005, 8:09:04 PM4/1/05
to
Sorry, missed the "empty" part. No, I don't think 3 sec for an enpty app is
reasonable. On the other hand on current smartphones (like C500) try
pressing Start and then 4, 8 (on my menu 4 is Settings, 8 is Calendar and 8
in Settings is Home Screen). YOu get Calendar. The whole thing is pretty
slow. I'm not even sure if making a C++ launcher will provide a definitive
answer

--
Alex Feinman
---
Visit http://www.opennetcf.org
"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message

news:022CE056-1CAC-48D2...@microsoft.com...

<ctacke/>

unread,
Apr 1, 2005, 10:28:14 PM4/1/05
to
Even if it took 3 minutes or 3 hours for the app to load I still fail to
understand how if 2 apps compete for the same mutex, how they both can be
getting it. Something's not right.

-Chris


"Alex Feinman [MVP]" <publi...@alexfeinman.com> wrote in message
news:uBsNEByN...@TK2MSFTNGP15.phx.gbl...

Sergey Bogdanov

unread,
Apr 2, 2005, 2:27:11 AM4/2/05
to
Agree with Chris, that it is really strange that mutex didn't work for
you. See this thread:

http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework/browse_frm/thread/986c4cca161413e3/3d4b2142b83ce8e9#3d4b2142b83ce8e9

and try to repeat this problem on this example:
http://www.sergeybogdanov.com/Samples/SPSingleInstance.zip

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com

Sylvain Fortin

unread,
Apr 2, 2005, 8:29:02 AM4/2/05
to
Hi everyone,

Sergey, I already tried the SPSingleInstance.zip example and I'm still able
to run multiple instances of my application. I agree with all of you guys
about “named mutex”, it's not the first time I'm using this technique to
insure I only have one instance of my application but this time it’s not
working and it doesn’t make any sense.

Alex, The device is a Motorola MPx220 and starting the calendar takes less
than 1 second. Most of the applications on the Smartphone have a load time of
less than 1 second.

Thanks for your time everyone, I really appreciate it.

Sylvain Fortin

<ctacke/>

unread,
Apr 2, 2005, 9:13:19 AM4/2/05
to
What do the calls to CreateMutex return in each case? Are they failing?

-Chris

"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message

news:6F69B3EC-BF91-433A...@microsoft.com...

Sylvain Fortin

unread,
Apr 4, 2005, 10:33:02 AM4/4/05
to
Hi Chris,

CreateMutex() always return a different number which looked like a valid
handle... But I verified the return value of GetLastError() and it returns 6
(ERROR_INVALID_HANDLE) at every call. Any idea?

Thanks for you time.

Sylvain Fortin

Chris Tacke, eMVP

unread,
Apr 4, 2005, 12:37:17 PM4/4/05
to
I've not looked at the pattenr object, but can you simply pull the
CreateMutex into your app's Main and run it there? Do the following
pseudocode:

if(CreateMutex("MutexName") == true)
{
if(GetLastError == ERROR_ALREADY_EXISTS)
MessageBox("Already Running");
else
MessageBox("First Instance");
}

Make sure your mutex handle's scope is such that it won't get destroyed
until your app closes, where you should call CloseHandle.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate

"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message

news:646C1D11-651B-413F...@microsoft.com...

Sylvain Fortin

unread,
Apr 4, 2005, 2:31:06 PM4/4/05
to
Hi Chris,

I wanted to confirm that I'm doing the right thing in a standard windows
application. So I created an empty windows application and I added the
following to test the "named mutex" code:

...

Private Const ERROR_ALREADY_EXISTS As Integer = 183

<DllImport("Kernel32.dll")> _
Private Shared Function GetLastError() As Integer
End Function

<DllImport("Kernel32.dll", EntryPoint:="CreateMutexW")> _
Private Shared Function CreateMutex(ByVal lpMutexAttributes As IntPtr,
ByVal InitialOwner As Boolean, ByVal MutexName As String) As Integer
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim nResult As Integer

If CreateMutex(IntPtr.Zero, True, "TestMutex") <> 0 Then
nResult = GetLastError()
If (nResult = ERROR_ALREADY_EXISTS) Then
MessageBox.Show(String.Format("Already Running - {0}", nResult))
Else
MessageBox.Show(String.Format("First Instance - {0}", nResult))
End If
End If
End Sub

...


In the standard windows application, everything worked has expected. So I
did the same thing with an empty smartdevice application and I added exactly
the same code except for the DLLImport, changed Kernel32.dll to CoreDLL.dll
to make it work on the smartphone. Same result... It didn't work and
GetLastError() returned 6 (ERROR_INVALID_HANDLE) at every calls. Any idea
what I did wrong?

Thanks for your time Chris.

Regards,

Sylvain Fortin

Chris Tacke, eMVP

unread,
Apr 4, 2005, 2:37:58 PM4/4/05
to
Don't call GetLastError, instead use System.Marshal.GetLastWin32Error() and
see if the result changes.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message

news:E9ECA0B0-02E4-4A6A...@microsoft.com...

Sylvain Fortin

unread,
Apr 4, 2005, 3:39:01 PM4/4/05
to
Hi Chris,

I changed the code like you told me to do and used
Marshal.GetLastWin32Error() instead. Marshal.GetLastWin32Error() always
return 0 and the application still think that CreateMutex() was successful in
creating the mutex (First instance).

Thanks for your time.

Regards,

Sylvain Fortin

Sergey Bogdanov

unread,
Apr 4, 2005, 4:01:48 PM4/4/05
to
Because you did not set SetLastError to true in DllImport attribute. Set
it and try again.

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com

Chris Tacke, eMVP

unread,
Apr 4, 2005, 4:19:50 PM4/4/05
to
I thought VB set it by default and C# did not.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Sergey Bogdanov" <sergey....@gmail.com> wrote in message
news:%239mRkEV...@TK2MSFTNGP14.phx.gbl...

Daniel Moth

unread,
Apr 4, 2005, 4:37:17 PM4/4/05
to
VB sets it by default only when you are using Declare afaik

Cheers
Daniel
--
http://www.danielmoth.com/Blog/


"Chris Tacke, eMVP" <cta...@spamfree-opennetcf.org> wrote in message
news:uAo$oOVOFH...@TK2MSFTNGP10.phx.gbl...

Sylvain Fortin

unread,
Apr 4, 2005, 4:43:07 PM4/4/05
to
Hi Sergey,

I made the following changes after reading your post and it's working now:

<DllImport("CoreDLL.dll", EntryPoint:="CreateMutexW", SetLastError:=True)> _


Private Shared Function CreateMutex(ByVal lpMutexAttributes As IntPtr, ByVal
InitialOwner As Boolean, ByVal MutexName As String) As Integer
End Function

Thanks to everyone who participate to this thread, I really appreciate the
time you spent helping me, everything works now, thanks!

Regards,

Sylvain Fortin

Sergey Bogdanov

unread,
Apr 4, 2005, 4:43:58 PM4/4/05
to
Oops, you are right.

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com

Sergey Bogdanov

unread,
Apr 4, 2005, 4:47:31 PM4/4/05
to
Strange... from [1]:
"true to indicate that the callee will call SetLastError; otherwise,
false. The default is false, except in Visual Basic."

[1]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservicesdllimportattributeclasssetlasterrortopic.asp

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com

Chris Tacke, eMVP

unread,
Apr 4, 2005, 5:12:34 PM4/4/05
to
Glad it worked. I knew there was a way to get it working correctly rather
than using a kludge.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Sylvain Fortin" <Sylvai...@discussions.microsoft.com> wrote in message

news:329053F6-A05F-46AA...@microsoft.com...

Chris Tacke, eMVP

unread,
Apr 4, 2005, 5:13:24 PM4/4/05
to
Who the hell thought of that?

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Daniel Moth" <dmo...@hotmail.com> wrote in message
news:OI5K7XV...@TK2MSFTNGP15.phx.gbl...

Chris Tacke, eMVP

unread,
Apr 4, 2005, 5:14:20 PM4/4/05
to
Apparently not always the case, as Sylvain discovered. There's something to
be said for explicitly setting even things that are the default (or at least
that you think is the default).

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


"Sergey Bogdanov" <sergey....@gmail.com> wrote in message

news:%23$dVHeVOF...@TK2MSFTNGP14.phx.gbl...

Daniel Moth

unread,
Apr 4, 2005, 5:18:45 PM4/4/05
to
Either my memory serves me wrong (won't be the first time) or the
documentation is wrong. Anyone care to prove one or the other (or has
Sylvain already done that)?

"Sergey Bogdanov" <sergey....@gmail.com> wrote in message

news:%23$dVHeVOF...@TK2MSFTNGP14.phx.gbl...

Sergey Bogdanov

unread,
Apr 5, 2005, 2:28:17 AM4/5/05
to
I have just tested it again it seems documentation is incorrect. The
SetLastError parameter must be explicitly set to receive the last error
from Marshal.GetLastWin32Error.

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com

Daniel Moth

unread,
Apr 5, 2005, 1:07:16 PM4/5/05
to
"It wasn't me"
"Don't shoot the messenger"

:-)


"Chris Tacke, eMVP" <cta...@spamfree-opennetcf.org> wrote in message

news:u1RcksVO...@TK2MSFTNGP10.phx.gbl...

Beorne

unread,
Jun 10, 2011, 5:08:24 AM6/10/11
to
Thank you very much, I had the same error with named mutex on WinCe (OneInstance.zip not working) And I resolved substituting pinvoke GetLastError with Marshal.GetLastWin32Error().

Thanks.

0 new messages